package main

import (
	"fmt"
	"html/template"
	"io"
	"log"
	"net/http"
	"os"
	"strings"
	"time"
)

func main() {
	//handleFunc()
	//handle()
	//httpServer()
	//handleCookie()
	//handleForm()
	handleFileUpload()
}

const tpl2 = `<!DOCTYPE html>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form method="post" action="/" enctype="multipart/form-data">
    <div class="form-group">
        <label class="form-control">附件(<a href="/?file={{.File}}">{{.File}}</a>):</label>
        <input class="form-control" type="file" name="file"/>
    </div>
    <button type="submit">上传</button>
</form>
</body>
</html>`

func handleFileUpload() {
	var preFile string
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		if r.Method == "GET" {
			r.ParseForm()
			f := r.Form.Get("file")
			if len(f) > 1 {
				if src, err := os.Open(f); err != nil {
					io.WriteString(w, err.Error())
				} else {
					defer src.Close()
					io.Copy(w, src)
				}
				return
			}
			data := map[string]string{
				"File": preFile,
			}
			t := template.New("file")
			t.Parse(tpl2)
			t.Execute(w, data)
		} else if f, fh, err := r.FormFile("file"); err != nil {
			io.WriteString(w, err.Error())
		} else {
			defer f.Close()
			if dest, err := os.OpenFile(fh.Filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.ModePerm); err != nil {
				io.WriteString(w, err.Error())
			} else {
				defer dest.Close()
				if _, err := io.Copy(dest, f); err != nil {
					io.WriteString(w, err.Error())
				} else {
					preFile = fh.Filename
				}
			}
		}
	})
	http.ListenAndServe(":8080", nil)
}

const tpl1 = `
<!DOCTYPE html>
<html>
<head>
    <title>Hey</title>
</head>
<body>
<form method="post" action="/">
    Username: <input type="text" name="uname">
    Password: <input type="password" name="pwd">
    <button type="submit">Submit</button>
</form>
</body>
</html>`

func handleForm() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		if r.Method == "GET" {
			t := template.New("hey")
			t.Parse(tpl1)
			t.Execute(w, nil)
		} else {
			io.WriteString(w, fmt.Sprintf("uname:%s\npwd:%s", r.FormValue("uname"), r.FormValue("pwd")))
		}
	})
	http.ListenAndServe(":8080", nil)
}

func handleCookie() {
	http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
		ck := &http.Cookie{
			Name:   "myCookie",
			Value:  "hello",
			Path:   "/",
			Domain: "localhost",
			MaxAge: 120,
		}
		http.SetCookie(writer, ck)
		ck2, err := request.Cookie("myCookie")
		if err != nil {
			io.WriteString(writer, err.Error())
			return
		}
		io.WriteString(writer, ck2.Value)
	})
	http.HandleFunc("/2", func(writer http.ResponseWriter, request *http.Request) {
		ck := &http.Cookie{
			Name:   "myCookie",
			Value:  "hello world",
			Path:   "/",
			Domain: "localhost",
			MaxAge: 120,
		}
		writer.Header().Set("Set-Cookie", strings.Replace(ck.String(), " ", "%20", -1))
		ck2, err := request.Cookie("myCookie")
		if err != nil {
			io.WriteString(writer, err.Error())
			return
		}
		io.WriteString(writer, ck2.Value)
	})
	http.ListenAndServe(":8080", nil)
}

//http://localhost:8080/hello
//http://localhost:8080/bye
func httpServer() {
	mux := make(map[string]func(w http.ResponseWriter, r *http.Request))
	server := &http.Server{Addr: ":8080", Handler: &myHandler2{mux: mux}, ReadTimeout: 5 * time.Second, WriteTimeout: 5 * time.Second}
	mux["/hello"] = func(writer http.ResponseWriter, request *http.Request) {
		io.WriteString(writer, "hello, this is the version 3.	")
	}
	mux["/bye"] = func(writer http.ResponseWriter, request *http.Request) {
		io.WriteString(writer, "bye bye, this is the version 3.	")
	}
	server.ListenAndServe()
}

//http://localhost:8080
//http://localhost:8080/hello
func handle() {
	mux := http.NewServeMux()
	var handler http.Handler = &myHandler1{}
	mux.Handle("/", handler)
	mux.HandleFunc("/hello", func(writer http.ResponseWriter, request *http.Request) {
		io.WriteString(writer, "hello, this is the version 2.")
	})
	dir, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
		return
	}
	//简易的静态文件服务器
	//go run http.go
	mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir(dir))))

	err = http.ListenAndServe(":8080", mux)
	if err != nil {
		log.Fatal(err)
	}
}

type myHandler2 struct {
	mux map[string]func(w http.ResponseWriter, r *http.Request)
}

//http://localhost:8080/1232131/123/21/4/14/12/4
func (h *myHandler2) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if v, ok := h.mux[r.URL.String()]; ok {
		v(w, r)
		return
	}
}

type myHandler1 struct {
}

//http://localhost:8080/1232131/123/21/4/14/12/4
func (myHandler1) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	io.WriteString(w, "URL:"+r.URL.String())
}
func handleFunc() {
	//设置路由
	http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
		io.WriteString(writer, "hello, this is the version 1.	")
	})
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		log.Fatal(err)
	}
}
